﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using Microsoft.Scripting.Utils;
using UnityEditor;
using UnityEngine;

namespace Motio.CSharp2Py
{
    public class Program
    {
        static void Main(string[] args)
        {
            if(args.Length < 2)
            {
                Console.WriteLine("This CLI is used to read a folder (and subfolder) full of .dll files and create python interfaces from the type found in each dll");
                Console.WriteLine("Usage:");
                Console.WriteLine("CSharp2Py [directory with dlls] [output directory] [regex match for each dll file]");
                return;
            }
            string dir = args[0];
            HierarchyBuilder hierarchy = new HierarchyBuilder()
            {
                BaseDir = args[1]
            };
            string arg = args.Length > 2 ? args[2] : "^[A-Za-z0-9]+$";
            Regex regex = new Regex(arg);

            foreach(string dll in Directory.GetFiles(dir, "*.dll"))
            {
                if(!regex.IsMatch(Path.GetFileName(dll)))
                    continue;
                Assembly assembly = Assembly.LoadFrom(dll);
                XDocument xmlDoc = FindXML(assembly);

                foreach (Type type in assembly.GetTypes())
                {
                    hierarchy.Add(new PythonClass(type, xmlDoc));
                }
                
            }

            hierarchy.CreateDirectories();
            hierarchy.CreateFiles();
        }

        static XDocument FindXML(Assembly assembly)
        {
            string path = Path.GetDirectoryName(assembly.Location);
            string file = Path.GetFileNameWithoutExtension(assembly.Location) + ".xml";
            string fullPath = Path.Combine(path, file);

            if (!File.Exists(fullPath))
                return null;

            return XDocument.Load(fullPath);
        }



        [MenuItem("unity-python/GenAPI_Assembles")]
        public static void GenLocal()
        {
            List<string> arg = new List<string>(){
                "Assembly-CSharp",
                "Unity.Python",//自身
            };
            Gen(arg);
        }

        [MenuItem("unity-python/GenAPI_Unity")]
        public static void GenUnity()
        {
            List<string> arg = new List<string>(){
                "UnityEngine",
                "UnityEngine.UI",
                "UnityEngine.CoreModule",
                "UnityEngine.PhysicsModule",
            };
            Gen(arg);
        }
        
        public static void Gen(List<string> arg )
        {
            StringBuilder print = new StringBuilder("This CLI is used to read a folder (and subfolder) full of .dll files and create python interfaces from the type found in each dll");
            print.AppendLine("This CLI is used to read a folder (and subfolder) full of .dll files and create python interfaces from the type found in each dll");
            print.AppendLine("Usage:");
            print.AppendLine("CSharp2Py [directory with dlls] [output directory] [regex match for each dll file]");
            Debug.Log(print.ToString());
            HierarchyBuilder hierarchy = new HierarchyBuilder()
            {
                BaseDir = Application.dataPath.Replace("Assets","Packages/IronPython.Interpreter.2.7.4/tools/Lib/site-packages")
            };
            float i = 0.0f;
            foreach(Assembly dll in AppDomain.CurrentDomain.GetAssemblies())
            {
                if(arg.FindIndex(f=>f == dll.GetName().Name)<0)
                    continue;
                XDocument xmlDoc = FindXML(dll);
                
                foreach (Type type in dll.GetTypes())
                {
                    EditorUtility.DisplayCancelableProgressBar("Parsing", dll.GetName().Name + "/" + type.Name, i++ / arg.Count);
                    hierarchy.Add(new PythonClass(type, xmlDoc));
                }
            }
            hierarchy.CreateDirectories();
            hierarchy.CreateFiles();
            EditorUtility.ClearProgressBar();
        }
    }
}
